home *** CD-ROM | disk | FTP | other *** search
/ Nebula 2 / Nebula Two.iso / SourceCode / MiscKit1.7.1 / MiscKit / Headers / misckit / SELECT.h < prev   
Encoding:
C/C++ Source or Header  |  1996-01-20  |  7.3 KB  |  187 lines

  1. //
  2. //    SELECT.h -- useful macros
  3. //        Written and copyright 1994, 1995, 1996 by Raf Schietekat.
  4. //                Version 1995-03-22.  All rights reserved.
  5. //        This notice may not be removed from this source code.
  6. //
  7. //    This code is included in the MiscKit by permission from the author
  8. //    and its use is governed by the MiscKit license, found in the file
  9. //    "LICENSE.rtf" in the MiscKit distribution.  Please refer to that file
  10. //    for a list of all applicable permissions and restrictions.
  11. //    
  12.  
  13. // These macros do not use the "MISC" prefix because that would ruin
  14. // their elegance.  If they cause you grief, just #define MISC_SKIP_SELECT
  15. // before importing the MiscBase.h or misckit.h...
  16.  
  17. /*
  18. WARNING!!!
  19. The number in E_ENDSELECT* should now include E_IFDEFAULT.
  20. Please adapt your code to comply (you'll be notified by a compilation failure
  21. if your code is affected).
  22. (E_SELECT/E_IFDEFAULT was not in the MiscKit before, so the change
  23. is transparent to its users.)
  24. */
  25.  
  26. /*
  27. Author: Raf Schietekat (RfSchtkt@maze.ruca.ua.ac.be on 1995-03-11)
  28. Copyright: Raf Schietekat, 1994, 1995
  29. License:
  30.   - You may use this code in your product without any fee, and you also don't
  31.   have to mention your use of this code.
  32.   - You may not change this file. If you want to, propose a change, and I
  33.   may agree to it. My purpose is to have only one version
  34.   of this code around, and to always have the best version :-).
  35.   - You should provide this code to anyone who asks for it, for free,
  36.   or covering the cost of the media only, and the recipient will be bound
  37.   by the same licence terms.
  38.   - This license does not limit my use of this code in any other way.
  39. License applications:
  40.   - GNU projects may use this file as long as any changes are made only in
  41.     the form of #undef/#define pairs external to this file, regardless of the
  42.     general GNU license terms. This file does not become part of GNU, and
  43.     the owner of the GNU license may not prohibit anyone from using this file
  44.     in a private project.
  45.   - Likewise, for the MiscKit in the NEXTSTEP world, the MiscKit administrator
  46.     may at most prepend an introductory comment to this file, but he should not
  47.     modify anything else. This file does not become part of the MiscKit
  48.     (except to the extent that it will remain available), and the MiscKit's
  49.     administrator may not prohibit anyone from extracting this file
  50.     from the MiscKit, removing the introductory comment by the MiscKit's
  51.     administrator, and using this file in a private project without
  52.     recognising the MiscKit.
  53.   - These are not really additions to the license, merely clarifications,
  54.     and similar rules apply to anyone else who redistributes this file.
  55. Guarantee: every imagineable disclaimer applies.
  56. Version:
  57.   1995-03-22: #define E_INTERMEZZO(c) E_IF(((c),0)) 0, not E_IF((c),0)
  58.   1995-03-11
  59. Maturity:
  60.   I use SELECT in nearly every source file I write; it works like a charm
  61. Acknowledgements: so far, only the author has contributed to this code
  62. */
  63.  
  64. /*
  65. Applicability: general C (pre-ANSI, ANSI, Objective-C, C++).
  66. To try the examples, transform !* *! into ... (ahem, I almost made this
  67.   file unusable), and maybe also the // which introduces a trailing comment in
  68.   Objective-C and C++ compilers.
  69. */
  70.  
  71. /********** a better selector **********/
  72.  
  73. #define SELECT          {if(0){
  74. #define   IF(c)           }else if(c){
  75. #define   IFDEFAULT       }else      {        /*optional*/
  76. #define   ENDSELECT       }}
  77. #define   IFNOT(c)      IF(!(c))
  78. #define   INTERMEZZO(c) IF(((c),0))
  79. /*
  80. You can use this as any {} block, both as a whole (e.g., for(;;) SELECT...),
  81. and within the clauses (you can define local variables).
  82. Contrived example (notice my plug of indentation style):
  83. >>>>>
  84. #import <stdio.h>
  85. #import "SELECT.h"
  86.  
  87. int main(int argc,char *argv[]){
  88.   !*var*! int a=5,b=4;
  89.   SELECT // this is always used to start the construct
  90.     printf("Don't put any code here: it will never be executed!");
  91.     IF(a==b)
  92.       // the prototypical case: if the condition is true
  93.       // the block is executed and the construct is exited, otherwise
  94.       // the next clause is tested
  95.       !*var*! int c; // you can declare local variables as in any {} block
  96.       c=a+b; printf("a=b, a+b=%i\n",c);
  97.     INTERMEZZO(printf("a=%i, b=%i\n",a,b))
  98.       // will unconditionally execute and always proceed to the next test
  99.       printf("Don't put any code here: it will never be executed!");
  100.     INTERMEZZO(printf("Multiple commands go into multiple INTERMEZZOs.\n"))
  101.       printf("Don't put any code here: it will never be executed!");
  102.     INTERMEZZO((printf("(Or you can use"),printf(" the comma operator,\n")))
  103.     INTERMEZZO(printf("but that's a bit awkward with the extra ().)\n"))
  104.     IFNOT(a<b) SELECT // to show appropriate nesting
  105.       IF(b<0) printf("b<0\n");
  106.       IFDEFAULT printf("Do stuff for 0<=b<=a\n");
  107.       ENDSELECT
  108.     IFDEFAULT
  109.       printf("IFDEFAULT must come last but is optional\n");
  110.     ENDSELECT // always end the construct with this ``keyword''
  111.   exit(0);
  112.   }
  113. <<<<<
  114. */
  115.  
  116.  
  117. /********** similarly for E_xpressions (less elegant, though) **********/
  118.  
  119. #define E_SELECT          ((0)?(0
  120. #define   E_IF(c)           ):((c)?(
  121. #define   E_IFDEFAULT       ):     (        /*required*/
  122. #define   E_ENDSELECT1      ))
  123. #define   E_ENDSELECT2      )))
  124. #define   E_ENDSELECT3      ))))
  125. #define   E_ENDSELECT4      )))))
  126. #define   E_ENDSELECT5      ))))))
  127. #define   E_ENDSELECT6      )))))))
  128. #define   E_ENDSELECT7      ))))))))
  129. #define   E_ENDSELECT8      )))))))))
  130. #define   E_ENDSELECT9      ))))))))))
  131. #define   E_ENDSELECT10     )))))))))))
  132. #define   E_ENDSELECT11     ))))))))))))
  133. #define   E_ENDSELECT12     )))))))))))))
  134. #define   E_ENDSELECT13     ))))))))))))))
  135. #define   E_ENDSELECT14     )))))))))))))))
  136. #define   E_ENDSELECT15     ))))))))))))))))
  137. #define   E_ENDSELECT16     )))))))))))))))))
  138. #define   E_ENDSELECT17     ))))))))))))))))))
  139. #define   E_ENDSELECT18     )))))))))))))))))))
  140. #define   E_ENDSELECT19     ))))))))))))))))))))
  141. #define   E_ENDSELECT20     )))))))))))))))))))))
  142. #define   E_IFNOT(c)      E_IF(!(c))
  143. #define   E_INTERMEZZO(c) E_IF(((c),0)) 0
  144. /*
  145. Designed to mirror the SELECT family, with these exceptions:
  146. - The content of the clauses is now a value, not the content of a block.
  147. - Unlike IFDEFAULT above, E_IFDEFAULT cannot be omitted.
  148. - E_ENDSELECT* requires specification of the total number
  149.   of clauses (including E_INTERMEZZO, as its definition reveals).
  150.   If you want more than 20 clauses, define additional macros
  151.   (externally to this file), and begin to wonder about your programming style.
  152. Contrived example (notice my plug of indentation style):
  153. >>>>>
  154. #import <stdio.h>
  155. #import "SELECT.h"
  156.  
  157. int main(int argc,char *argv[]){
  158.   !*var*! int minValue=3,value=1000,maxValue=6;
  159.   printf("%i constrained to [%i,%i] is %i.\n",
  160.     value,
  161.     minValue,maxValue,
  162.     E_SELECT
  163.       E_IFNOT(minValue<=value          ) minValue
  164.       E_IFNOT(          value<=maxValue) maxValue
  165.       E_IFDEFAULT                        value
  166.       E_ENDSELECT3
  167.     );
  168.   exit(0);
  169.   }
  170. <<<<<
  171. */
  172.  
  173.  
  174. /***** overriding fall-through as the default in a switch statement *****/
  175.  
  176. #define CASE      break;case
  177. #define DEFAULT   break;default
  178. /*
  179. Contrived example (notice my plug of indentation style):
  180.   switch(n){
  181.     case 0: printf("always use case, not CASE, for the first clause\n");
  182.       // to avoid a spurious warning by overzealous compilers
  183.     CASE 1: printf("isn't the absence of ``break'' a liberation?\n");
  184.     DEFAULT: printf("and that's the last one\n");
  185.     }
  186. */
  187.